package mpo.core;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class SimilarCalcuate {
	/**
	 * 
	 * @Title: cosSimilarityByString
	 * @Description: 得到两个字符串的相似性
	 * @param @param first
	 * @param @param second
	 * @param @return
	 * @return Double
	 * @throws
	 */
	public static Double cosSimilarityByString(String first, String second) {
		try {
			Map<String, Integer> firstTfMap = TfIdfAlgorithm.segStr(first);
			Map<String, Integer> secondTfMap = TfIdfAlgorithm.segStr(second);
			if (firstTfMap.size() < secondTfMap.size()) {
				Map<String, Integer> temp = firstTfMap;
				firstTfMap = secondTfMap;
				secondTfMap = temp;
			}

			return calculateCos(firstTfMap, secondTfMap);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0d;
	}

	/**
	 * 
	 * @Title: calculateCos
	 * @Description: 计算余弦相似性
	 * @param @param first
	 * @param @param second
	 * @param @return
	 * @return Double
	 * @throws
	 */
	private static Double calculateCos(Map<String, Integer> first,
			Map<String, Integer> second) {

		List<Map.Entry<String, Integer>> firstList = new ArrayList<Map.Entry<String, Integer>>(
				first.entrySet());
		List<Map.Entry<String, Integer>> secondList = new ArrayList<Map.Entry<String, Integer>>(
				second.entrySet());
		// 计算相似度
		double vectorFirstModulo = 0.00;// 向量1的模
		double vectorSecondModulo = 0.00;// 向量2的模
		double vectorProduct = 0.00; // 向量积
		int secondSize = second.size();
		for (int i = 0; i < firstList.size(); i++) {
			if (i < secondSize) {
				vectorSecondModulo += secondList.get(i).getValue()
						.doubleValue()
						* secondList.get(i).getValue().doubleValue();
				vectorProduct += firstList.get(i).getValue().doubleValue()
						* secondList.get(i).getValue().doubleValue();
			}
			vectorFirstModulo += firstList.get(i).getValue().doubleValue()
					* firstList.get(i).getValue().doubleValue();
		}
		return vectorProduct
				/ (Math.sqrt(vectorFirstModulo) * Math.sqrt(vectorSecondModulo));
	}
}
